using B.Z.BasicData.Infrastructure;
using B.Z.Inventory.API.Read.Application.Command;
using B.Z.Inventory.API.Read.DTO;
using B.Z.Inventory.Domain;
using B.Z.Inventory.ErrorCode;
using MediatR;
using Microsoft.EntityFrameworkCore;

namespace B.Z.Inventory.API.Read.Application.CommandHandler
{
    /// <summary>
    /// 出入库统计查询命令处理器
    /// </summary>
    public class InOutboundStatisticsCommandHandler : IRequestHandler<InOutboundStatisticsCommand, APIResult<InOutboundStatisticsDto>>
    {
        private readonly IBaseRepository<T_IntOutStore> intOutStoreRepository;
        private readonly ILogger<InOutboundStatisticsCommandHandler> logger;

        public InOutboundStatisticsCommandHandler(
            IBaseRepository<T_IntOutStore> intOutStoreRepository,
            ILogger<InOutboundStatisticsCommandHandler> logger)
        {
            this.intOutStoreRepository = intOutStoreRepository;
            this.logger = logger;
        }

        public Task<APIResult<InOutboundStatisticsDto>> Handle(InOutboundStatisticsCommand request, CancellationToken cancellationToken)
        {
            APIResult<InOutboundStatisticsDto> result = new APIResult<InOutboundStatisticsDto>();
            result.Code = APIEnums.ok;

            try
            {
                // 获取出入库记录
                var query = intOutStoreRepository.GetAll()
                    .AsNoTracking()
                    .Where(x => !x.IsDelete);

                // 应用时间筛选
                if (request.StartDate.HasValue)
                {
                    query = query.Where(x => x.IntOutStoreTime >= request.StartDate.Value);
                }

                if (request.EndDate.HasValue)
                {
                    query = query.Where(x => x.IntOutStoreTime <= request.EndDate.Value);
                }

                // 应用仓库筛选
                if (request.StoreId.HasValue)
                {
                    query = query.Where(x => x.StoreId == request.StoreId.Value);
                }

                // 应用商品筛选
                if (request.GoodsId.HasValue)
                {
                    query = query.Where(x => x.GoodsIds == request.GoodsId.Value.ToString());
                }

                var records = query.ToList();

                // 计算总体统计
                var inboundRecords = records.Where(x => x.IsIntOrOut).ToList();
                var outboundRecords = records.Where(x => !x.IsIntOrOut).ToList();

                var totalInboundQuantity = inboundRecords.Sum(x => x.Count);
                var totalOutboundQuantity = outboundRecords.Sum(x => x.Count);

                var statistics = new InOutboundStatisticsDto
                {
                    StartDate = request.StartDate,
                    EndDate = request.EndDate,
                    TotalInboundQuantity = totalInboundQuantity,
                    TotalOutboundQuantity = totalOutboundQuantity,
                    InboundOperationCount = inboundRecords.Count,
                    OutboundOperationCount = outboundRecords.Count,
                    NetInventoryChange = totalInboundQuantity - totalOutboundQuantity
                };

                // 如果需要每日统计明细
                if (request.IncludeDailyDetails)
                {
                    var dailyStats = records
                        .Where(x => x.IntOutStoreTime.HasValue)
                        .GroupBy(x => x.IntOutStoreTime.Value.Date)
                        .Select(g => new DailyInOutStatistics
                        {
                            Date = g.Key,
                            InboundQuantity = g.Where(x => x.IsIntOrOut).Sum(x => x.Count),
                            OutboundQuantity = g.Where(x => !x.IsIntOrOut).Sum(x => x.Count)
                        })
                        .OrderBy(x => x.Date)
                        .ToList();

                    // 计算每日净变化
                    foreach (var daily in dailyStats)
                    {
                        daily.NetChange = daily.InboundQuantity - daily.OutboundQuantity;
                    }

                    statistics.DailyStatistics = dailyStats;
                }

                result.Data = statistics;

                logger.LogInformation($"成功获取出入库统计，入库总量：{totalInboundQuantity}，出库总量：{totalOutboundQuantity}");
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "获取出入库统计时发生错误");
                result.Code = APIEnums.fail;
                result.Message = "获取出入库统计失败";
            }

            return Task.FromResult(result);
        }
    }
}